package com.ddwl.goods.service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.constant.GateEnum;
import com.ddwl.common.constant.RedisKey;
import com.ddwl.common.feign.api.GateApi;
import com.ddwl.common.feign.api.ShopApi;
import com.ddwl.common.service.RedisService;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.goods.mapper.ItemAgentMapper;
import com.ddwl.goods.model.ItemAgent;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.goods.ItemAgentBo;
import com.ddwl.schema.bo.goods.ItemSearchBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.goods.ItemAgentVo;
import com.ddwl.schema.vo.goods.ItemVo;
import com.ddwl.schema.vo.shop.ShopVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 代理商品
 *
 * @author Fu Zhaohui
 * @version 1.0.0
 * @date 2021/6/25 17:44
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ItemAgentService {

    private final ItemAgentMapper itemAgentMapper;
    private final GateApi gateApi;
    private final ShopApi shopApi;
    private final RedisService redisService;
    private final ItemService itemService;


    public PageVo<ItemAgentVo> page(PageBo<ItemSearchBo> pageBo) {
        ItemSearchBo param = pageBo.getParam();
        PageVo<ItemAgentVo> pageVo = new PageVo<>();
        pageVo.setPage(pageBo.getPage());
        pageVo.setSize(pageBo.getPageSize());
        Example example = new Example(ItemAgent.class);
        example.and().andEqualTo("dflag", BaseEnum.DflagEnum.NOT_DELETE.getCode())
                .andEqualTo("status", param.getStatus());
        if (StringUtils.hasText(param.getMchId())) {
            example.and().andEqualTo("mchId", param.getMchId());
        }
        if (StringUtils.hasText(param.getShopId())) {
            example.and().andEqualTo("shopId", param.getShopId());
        }
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize());
        Page<ItemAgent> pageable = (Page<ItemAgent>) itemAgentMapper.selectByExample(example);
        pageVo.setTotal(pageable.getTotal());
        List<ItemAgent> entities = pageable.getResult();
        if (entities.isEmpty()) {
            pageVo.setData(new ArrayList<>(0));
            return pageVo;
        }
        List<String> itemIds = entities.stream().map(ItemAgent::getItemId).collect(Collectors.toList());
        List<ItemVo> items = itemService.getByItemIds(itemIds);
        Map<String, ItemVo> itemMap = items.stream().collect(Collectors.toMap(ItemVo::getId, Function.identity()));
        pageVo.setData(entities.stream().map(entity -> {
            ItemAgentVo vo = BeanConverUtils.convertBean(entity, ItemAgentVo.class);
            vo.setItem(itemMap.get(entity.getItemId()));
            return vo;
        }).collect(Collectors.toList()));
        return pageVo;
    }

    /**
     * 代理商品  支持批量更新修改
     * @param bos
     */
    @Transactional(rollbackFor = Throwable.class)
    public void proxy(List<ItemAgentBo> bos) {
        if (bos.isEmpty()) {
            return;
        }
        bos.forEach(bo -> {
            ItemAgent params = new ItemAgent();
            params.setItemId(bo.getItemId());
            params.setShopId(bo.getShopId());
            ItemAgent entity = itemAgentMapper.selectOne(params);
            if (entity == null) {
                entity = BeanConverUtils.convertBean(bo, ItemAgent.class);
                entity.setId(UUIDGenerator.getShortUUID());
                ItemVo item = itemService.getItem(bo.getItemId());
                entity.setWxaCode(getWxaCodeOSSUrl(bo.getShopId(), bo.getItemId(), item.getItemImage()));
                itemAgentMapper.insertSelective(entity);
            } else {
                BeanUtils.copyProperties(bo, entity, "id");
                entity.setDflag(BaseEnum.DflagEnum.NOT_DELETE.getCode());
                itemAgentMapper.updateByPrimaryKeySelective(entity);
            }
        });
    }

    public void update(ItemAgentBo bo) {
        itemAgentMapper.updateByPrimaryKeySelective(BeanConverUtils.convertBean(bo, ItemAgent.class));
    }

    public ItemAgentVo info(String itemId, String shopId) {
        ItemAgent itemAgent = new ItemAgent();
        itemAgent.setItemId(itemId);
        itemAgent.setShopId(shopId);
        itemAgent.setDflag(BaseEnum.DflagEnum.NOT_DELETE.getCode());
        //itemAgent.setStatus(BaseEnum.StatusEnum.ENABLE.getCode());
        return BeanConverUtils.convertBean(itemAgentMapper.selectOne(itemAgent), ItemAgentVo.class);
    }

    public void delete(String id) {
        ItemAgent itemAgent = new ItemAgent();
        itemAgent.setId(id);
        itemAgent.setDflag(BaseEnum.DflagEnum.DELETED.getCode());
        itemAgentMapper.updateByPrimaryKeySelective(itemAgent);
    }

    /**
     * 获取代理商品小程序码
     *
     * @param shopId
     * @param itemId
     * @return
     */
    public String getWxaCodeOSSUrl(String shopId, String itemId, String itemPic) {
        String imageName = itemId + "_" + shopId;
        Map<String, String> params = new HashMap<>(2);
        params.put("itemId", itemId);
        params.put("shopId", shopId);
        String uuid = RandomUtil.randomString(32);
        redisService.getHashOps().putAll(RedisKey.SHARE_CODE_INFO.getKey(uuid), params);
        RestVo<String> stringRestVo = gateApi.customizeLogoWxaCodeUrl(uuid, BaseEnum.WxAppId.WBM.getCode(), String.format(GateEnum.WxaPath.ITEM_WXA_CODE.getPath(), imageName), itemPic.replace("https://58d.oss-cn-hangzhou.aliyuncs.com/", ""), GateEnum.WbmMinAppPage.ITEM_INDEX.getPath());
        if (StrUtil.isEmpty(stringRestVo.getResult())) {
            return null;
        }
        return stringRestVo.getResult();
    }

    public List<String> agentShopIds(String itemId) {
        ItemAgent itemAgent = new ItemAgent();
        itemAgent.setItemId(itemId);
        itemAgent.setDflag(BaseEnum.DflagEnum.NOT_DELETE.getCode());
        List<ItemAgent> itemAgents = itemAgentMapper.select(itemAgent);
        return itemAgents.stream().map(ItemAgent::getShopId).collect(Collectors.toList());
    }

    public void downWxaCode(HttpServletResponse response, List<String> agentIds, String shopId) {
        if (CollectionUtils.isEmpty(agentIds) || !StringUtils.hasText(shopId)) {
            return;
        }
        Example example = new Example(ItemAgent.class);
        example.and().andIn("id", agentIds)
                .andEqualTo("dflag", BaseEnum.DflagEnum.NOT_DELETE.getCode());
        List<ItemAgent> itemAgents = itemAgentMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(itemAgents)) {
            return;
        }
        List<String> itemIds = itemAgents.stream().filter(itemAgent -> StringUtils.hasText(itemAgent.getWxaCode())).map(ItemAgent::getItemId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(itemIds)) {
            return;
        }
        itemService.downWxaCode(response, itemIds, shopId);
    }

    /**
     * 查询商品代理门店列表
     *
     * @param pageBo
     * @return
     */
    public PageVo<ItemAgentVo> shops(PageBo<ItemAgentBo> pageBo) {
        PageVo<ItemAgentVo> pageVo = new PageVo<>();
        pageVo.setPage(pageBo.getPage());
        pageVo.setSize(pageBo.getPageSize());
        ItemAgent param = new ItemAgent();
        param.setItemId(pageBo.getParam().getItemId());
        param.setDflag(BaseEnum.DflagEnum.NOT_DELETE.getCode());
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize());
        Page<ItemAgent> pageable = (Page<ItemAgent>) itemAgentMapper.select(param);
        pageVo.setTotal(pageable.getTotal());
        List<ItemAgent> entities = pageable.getResult();
        if (entities.isEmpty()) {
            pageVo.setData(new ArrayList<>());
            return pageVo;
        }
        List<String> shopIds = entities.stream().map(ItemAgent::getShopId).collect(Collectors.toList());
        List<ShopVo> shops = shopApi.getShopListByIds(shopIds).getResult();
        Map<String, ShopVo> shopMap = shops.stream().collect(Collectors.toMap(ShopVo::getId, Function.identity()));
        pageVo.setData(entities.stream().map(entity -> {
            ItemAgentVo vo = BeanConverUtils.convertBean(entity, ItemAgentVo.class);
            vo.setShop(shopMap.get(vo.getShopId()));
            return vo;
        }).collect(Collectors.toList()));
        return pageVo;
    }
}
